var DBG_APP_NAME = "["+chrome.i18n.getMessage("app_name")+"]";

// supported colors
var colors = [
  [chrome.i18n.getMessage("color_red"), "#FF0000", null], // null values will be replaced with menuItems ids
  [chrome.i18n.getMessage("color_green"), "#00FF00", null],
  [chrome.i18n.getMessage("color_blue"), "#0000FF", null],
  [chrome.i18n.getMessage("color_pink"), "#FF99FF", null],
  [chrome.i18n.getMessage("color_yellow"), "#FFFF00", null],
  [chrome.i18n.getMessage("color_purple"), "#CC00FF", null]
];

var tagMenuItems = null; // tagMenuItems current ids
var untagMenuItem = null; // untagMenuItem current id

/**********************************
 * EVENTS
 **********************************/

// listener for incoming messages (contentscript and popup)
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
    switch (request.cmd) {
        /// update context menus according to current element
        /// Receives [cmd, linkUrl] from content script
        case "updateContextMenu" :
            removeAllCustomMenuItems();
            // linkUrl is null if the link has no href
            if (request.linkUrl != null) {
                var tagColor = getKey(request.linkUrl);
                if (tagColor != null && tagColor != "") {
                    var selectedMenuItem = 0;
                    while (colors[selectedMenuItem][1] != tagColor && selectedMenuItem != colors.length) {
                        selectedMenuItem++;
                    }
                    tagMenuItems = createTagMenuItems(selectedMenuItem);
                    untagMenuItem = createUntagMenuItem();
                }
                else {
                    // no tag = no untag + no selection
                    tagMenuItems = createTagMenuItems(null);
                }
            }
            sendResponse({}); // notify..
            break;
        
        /// Clear context menus
        /// Receives [cmd] from content script
        case "clearMenu" :
            removeAllCustomMenuItems();
            sendResponse({}); // notify..
            break;
            
        /// return tagged links according to current pages's links
        /// Receives [cmd, data] from content script
        /// Sends [links, colors] to content script
        case "getTaggedLinks" :
            var links = request.data.split(",");
            var taggedLinks = [];
            var taggedColors = [];
            for (var i=0; i<links.length; i++) {
                var color = null;
                if ((color=getKey(links[i])) != null) {
                    taggedLinks.push(links[i]);
                    taggedColors.push(color);
                }
            }
            if (taggedLinks.length > 0) {
                taggedLinks = taggedLinks.join(",");
                taggedColors = taggedColors.join(",");
                sendResponse({
                    links: taggedLinks,
                    colors: taggedColors
                });
            }
            else {
                sendResponse({
                    links: null,
                    colors: null
                });
            }
            break;
        
        /// delete a batch of tags marked for removal
        /// Receives [cmd, links] from popup
        case "batchRemove" :
            var links = request.links.split(",");
            for (var i=0; i<links.length; i++) {
                removeKey(links[i]);
            }
            sendResponse({}); // notify..
            break;
    }
});

/**********************************
 * METHODS
 **********************************/

function createTagMenuItems(selectedItem) {
    var menuItems = [];
    for (var i=0; i<colors.length; i++) {
        try {
            menuItems[i] = chrome.contextMenus.create({
                "title": colors[i][0],
                "contexts": ["link"],
                "type": "checkbox",
                "checked": (selectedItem!=null && i==selectedItem),
                "onclick": tagLink
            });
            colors[i][2] = menuItems[i];
        } catch (e) {
            i--; // don't penalize other menus if one crashes
        }
    }
    return menuItems; // return ids
}

function createUntagMenuItem() {
    var id = null;
    try {
        id = chrome.contextMenus.create({
            "title": chrome.i18n.getMessage("contextmenus_removeTag"),
            "contexts": ["link"],
            "onclick": untagLink
        }); // return id
    } catch (e) {}
    return id;
}

function removeAllCustomMenuItems() {
    if (tagMenuItems != null) {
        for (var i=0; i<tagMenuItems.length; i++) {
            chrome.contextMenus.remove(tagMenuItems[i]);
        }
        tagMenuItems = null;
    }
    if (untagMenuItem != null) {
        chrome.contextMenus.remove(untagMenuItem);
        untagMenuItem = null;
    }
}

function tagLink(info, tab) {
    // just ensuring that we're not about to tag a link that has no href or a crashed url
    if (info.linkUrl != null && info.linkUrl != undefined) {
        // trouver la couleur qui a le id de menu en cours
        var colorEntry = 0;
        while (colors[colorEntry][2] != info.menuItemId && colorEntry != colors.length)
            colorEntry++;
    
        var url = getDirectUrl(info.linkUrl);
        
        setKey(url, colors[colorEntry][1]); // key value is the color associated to the url
        
        // request a tag update to the current page
        sendRequestToCurrentTab({cmd:"updateTags"}, function(response) {
            //...
        });
    }
}

function untagLink(info, tab) {
    // just ensuring that we're not about to untag a link that has no href or a crashed url
    if (info.linkUrl != null && info.linkUrl != undefined) {
        var url = getDirectUrl(info.linkUrl);
        
        // the next update will reset the color of the link
        setKey(url, "");
    
        // request a tag update to the current page, then remove the key
        sendRequestToCurrentTab({cmd:"updateTags"}, function(response) {
            removeKey(url);
        });
    }
}

/**********************************
 * UTILS
 **********************************/

// prevent tagging some popular redirecting patterns or messed up urls that will change everytime
function getDirectUrl(url) {
    var directUrl = url;
    // popular redirecting pattern
    if (url != undefined && url.indexOf("=http") > -1) {
        try {
            directUrl = "http"+unescape(url.split("=http")[1].split("&")[0]);
        } catch (e) {
            console.log("failed to convert url "+url);
        }
    }
    // specific to google results page numbers
    else if (url.indexOf("google.") > -1 && url.indexOf("ei=") > -1) {
        var left = url.split("ei=")[0];
        var right = url.substring(left.length).split("&")[1];
        directUrl = left + right;
    }
    return directUrl;
}

function setKey(key, value) {
    try {
        window.localStorage.removeItem(key);
        window.localStorage.setItem(key, value);
    } catch (e) {
        console.log(DBG_APP_NAME+e);
    }
}

function getKey(key) {
    var value = null;
    try {
        value = window.localStorage.getItem(key);
    } catch (e) {
        console.log(DBG_APP_NAME+e);
    }
    if (value == undefined) {
        value = null;
    }
    return value;
}

function removeKey(key) {
    try {
        window.localStorage.removeItem(key);
    } catch (e) {
        console.log(DBG_APP_NAME+e);
    }
}

function sendRequestToCurrentTab(args, callback) {
    chrome.tabs.getSelected(null, function(tab) {
        chrome.tabs.sendRequest(tab.id, args, callback);
    });
}
